package com.application.service;

import com.application.common.OrderStatus;
import com.application.model.*;
import com.application.service.orderbusi.OrderNotifyFactory;
import com.application.service.pay.OrderPojo;
import com.application.service.pay.RefundPojo;
import com.jfinal.aop.Before;
import com.jfinal.ext.util.DateUtil;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.platform.annotation.Service;
import com.platform.mvc.base.BaseService;
import com.platform.mvc.user.User;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service(name = OrderService.serviceName)
public class OrderService extends BaseService {

    @SuppressWarnings("unused")
    private static final Log log = Log.getLog(OrderService.class);

    public static final String serviceName = "orderService";

    /**
     * 创建订单
     * 逻辑:
     * 1.保存订单,
     * (以下可选,需要更新用户信息)
     * 5.记录优惠券消费明细,
     * 6.记录积分消费明细,
     */
    @Before(Tx.class)
    public Order createOrder(User user, int orderType, int moduleId, BigDecimal realPrice, int userPoint) {
        int userid = user.getId();

        BigDecimal usePoint = new BigDecimal(userPoint).divide(new BigDecimal(100));
        //封装数据
        BigDecimal totalAmount = realPrice.subtract(new BigDecimal("0")).subtract(usePoint);

        Order order = new Order();
        Date date = new Date();
        order.set("order_userid", userid)
                .set("order_username", user.getUsername())
                .set("order_status", OrderStatus.PAY_WAIT)
                .set("order_type", orderType)
                .set("module_id", moduleId)
                .set("order_memo", null)
                .set("order_price", realPrice)
                .set("order_date", new SimpleDateFormat("yyyyMMdd").format(date))
                .set("use_point", usePoint).set("create_time", date)
                .set("order_no", getOrderNo(orderType))
                .set("total_amount", totalAmount);

        order.save();

        OrderFlow.dao.create(order.getId(), OrderStatus.PAY_WAIT, userid, "创建订单");
//        afterCreateOrder(userPoint, userid, order.getId());
        return order;
    }

    private String getOrderNo(Integer orderType) {
        String s = "";
        switch (orderType) {
            case Order.TYPE_VIP_CHARGE:
                s = "v";
                break;
            case Order.TYPE_PLAY_COUPON:
                s = "p";
                break;
            case Order.TYPE_COURSE:
                s = "c";
                break;
        }
        return s + StrKit.getRandomNo();
    }

    /**
     * 状态变更
     */
    @Deprecated
    private void afterCreateOrder(int userPoint, int userid, int orderId) {
        //记录积分消费
        if (userPoint > 0) {
            UserPoint.dao.create(userid, userPoint, UserPoint.type_order_cost, orderId);
        }
    }



    /*
    支付完成后,修改订单状态
     */
    public boolean updateOrderStatus(Order order, String orderNo, String payTime, String payAmount, String payType) {
        boolean rs = Db.tx(() -> {
            Timestamp time = new Timestamp(System.currentTimeMillis());
            order.setPay_time(payTime == null ? time : new Timestamp(DateUtil.parseDate(payTime, "yyyyMMddHHmmss").getTime()));
            order.setOrder_status(OrderStatus.PAY_OVER);
            order.setPay_type(payType);
            order.setPay_amount(new BigDecimal(payAmount));
            order.setUpdate_time(time);
            boolean f1 = order.update();
            boolean f2 = OrderNotifyFactory.getObject(orderNo).handler(order);

            return f1 && f2;
        });

        return rs;
    }

    /*
    1.根据支付方式申请退款操作，订单退款仅支持已付款未发货状态，不涉及返利与返送积分，但涉及用户消费金额
    2.第一步成功之后,变更订单状态
    3.订单流程添加
     */
    public boolean handlerRefund(Integer orderId, Integer resultStatus, int userid) {
        Order o = Order.dao.findById(orderId);

        OrderRefund ref = OrderRefund.dao.findByOrderId(orderId);

        boolean rs = Db.tx(() -> {
            Integer orderStatus = resultStatus == OrderRefund.RESULT_SUCCESS ? OrderStatus.REFUND_OVER : OrderStatus.REFUND_REJECT;

            //更新订单状态
            o.setOrder_status(orderStatus);
            o.update();

            //处理退款信息
            OrderRefund.dao.answer(ref.getId(), userid, resultStatus);

            //更新订单流
            OrderFlow.dao.create(orderId, orderStatus, userid, ref.getRefund_reason());

             /*
            根据订单支付类型处理
             */
            boolean f;
            if (resultStatus == OrderRefund.RESULT_SUCCESS) {
                /*if (Order.PAY_ZFB.equalsIgnoreCase(o.getPay_type())) {
                    f = PayUtil.refund(o.getOrder_no(), ref.getRefund_amount(), ref.getRefund_reason(), ref.getId().toString());
                } else if (Order.PAY_WX.equalsIgnoreCase(o.getPay_type())) {
                    f = PayUtil.wxRefund(o.getOrder_no(), ref.getId(), ref.getRefund_amount(), o.getPay_amount().toString());
                } else if(Order.PAY_XCX.equalsIgnoreCase(o.getPay_type())) {
                    f = PayUtil.xcxRefund(o.getOrder_no(), ref.getId(), ref.getRefund_amount(), o.getPay_amount().toString());
                } else {
                    f = yeRefund(userid, o, ref);
                }*/
                RefundPojo pojo = new RefundPojo(o, ref, userid);
                f = ServiceFactory.getPayObject(o.getPay_type()).refund(pojo);
            } else {
                f = true;
            }
            return f;
        });

        return rs;
    }


    public Map<String, Object> pay(int payType, OrderPojo pojo) throws Exception {
        Object obj = ServiceFactory.getPayObject(String.valueOf(payType)).getPayInfo(pojo);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("pay_type", payType);
        resultMap.put("order_id", pojo.getOrder().getId());
        resultMap.put("pay_info", obj);
        return resultMap;
    }


    /**
     * 支付完成回调时，增加返利信息
     * @param id
     * @param userid
     * @return
     */
    public boolean receiveProduct(Integer id, Integer opUserId) {
        boolean f = false;
        f = Db.tx(() -> {
            Order o = Order.dao.findById(id);
            int userid = opUserId == null ? o.getOrder_userid() : opUserId;
            o.setOrder_status(OrderStatus.TAKE_OVER);
            o.update();
            //创建流程
            OrderFlow.dao.create(id, OrderStatus.TAKE_OVER, userid, "确认收货");
            //增加积分
            addUserPoint(o);
            //上线返利
//            Rebate.dao.rebate(id, userid, o.getOrder_no());
            return true;
        });
        return f;
    }

    private void addUserPoint(Order order) {
        Global global = Global.cacheGetByCode(Global.Code.order_giftPoint);
        NumberFormat nf= NumberFormat.getPercentInstance();
        try {
            Number number = nf.parse(global.getValue());
            BigDecimal gift = order.getPay_amount().multiply(new BigDecimal(number.doubleValue()));
            UserPoint.dao.create(order.getOrder_userid(), gift.intValue(), UserPoint.type_order_gift, order.getId());

        } catch (ParseException e) {
            e.printStackTrace();
        }
    }


}
